/*
 *
 *  Copyright (C) 2012-2024
 *  All rights reserved, Designed By 杭州连线客信息技术有限公司
 *  注意：
 *  本软件为杭州连线客信息技术有限公司开发研制，未经购买不得使用
 *  购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
 *  一经发现盗用、分享等行为，将追究法律责任，后果自负
 *
 */

package com.lxk.oms.postorder.flow.refund;

import cn.hutool.core.util.ObjectUtil;
import com.lxk.event.helper.EventHelper;
import com.lxk.event.oms.OrderOptionLogEvent;
import com.lxk.event.oms.enums.OrderEnums;
import com.lxk.oms.flow.cancel.CancelOrderContext;
import com.lxk.oms.order.domain.OmsOrder;
import com.lxk.oms.order.domain.req.CancelOrderReq;
import com.lxk.oms.order.domain.vo.OmsOrderVo;
import com.lxk.oms.order.manger.OrderManger;
import com.lxk.oms.order.service.IOmsOrderService;
import com.lxk.oms.postorder.domain.enums.PostOrderEnums;
import com.lxk.oms.postorder.domain.vo.OmsPostOrderItemVo;
import com.lxk.oms.postorder.domain.vo.OmsPostOrderVo;
import com.lxk.oms.postorder.service.IOmsPostOrderService;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.log.LFLog;
import com.yomahub.liteflow.log.LFLoggerManager;
import lombok.AllArgsConstructor;
import org.dromara.common.core.exception.ServiceException;

import java.math.BigDecimal;
import java.util.List;

import static com.lxk.event.oms.enums.OrderEnums.PostStatus.*;
import static com.lxk.oms.postorder.flow.refund.FlowRefundPostOrderNodeConst.REFUND_POST_ORDER_NODE;

/**
 * 仅退款处理
 *
 * @author heyi
 * 2024/9/29
 */
@AllArgsConstructor
@LiteflowComponent(value = REFUND_POST_ORDER_NODE)
public class PostOrderRefundNode extends NodeComponent {
    private final LFLog log = LFLoggerManager.getLogger(FlowExecutor.class);
    private final IOmsPostOrderService omsPostOrderService;
    private final OrderManger orderManger;
    private final IOmsOrderService omsOrderService;

    @Override
    public void beforeProcess() {
        PostOrderRefundContext contextBean = this.getContextBean(PostOrderRefundContext.class);
        OmsPostOrderVo postOrder = contextBean.getPostOrder();
        OmsOrderVo order = contextBean.getOrder();
        Boolean success = omsPostOrderService.updateStatus(postOrder.getId(), PostOrderEnums.PostOrderStatus.REVIEW, PostOrderEnums.PostOrderStatus.COMPLETED);
        if (!success) {
            throw new ServiceException("售后订单已处理");
        }
        Boolean success1 = omsOrderService.updateOrderPostStatus(order.getId(), ING_1, SUCCESS_2);
        if (!success1) {
            throw new ServiceException("订单售后状态异常");
        }
        Integer postType = postOrder.getPostType();
        if (ObjectUtil.notEqual(postType, PostOrderEnums.PostOrderType.REFUND.getPostOrderType())) {
            throw new ServiceException("订单售后类型不符");
        }
    }

    @Override
    public void process() throws Exception {
        PostOrderRefundContext contextBean = this.getContextBean(PostOrderRefundContext.class);
        Long userId = contextBean.getUserId();
        String userType = contextBean.getUserType();
        OmsOrderVo order = contextBean.getOrder();
        List<OmsPostOrderItemVo> omsPostOrderItemVos = contextBean.getOmsPostOrderItemVos();
        String orderNo = order.getOrderNo();
        OmsPostOrderVo postOrder = contextBean.getPostOrder();
        CancelOrderReq req = new CancelOrderReq();
        req.setUserId(userId);
        req.setUserType(userType);
        req.setOrderNo(orderNo);
        req.setCancelCode(calCancelCode(postOrder.getActRefundAmount(), order.getRefundAmount(), order.getActPayPrice(), order.getStatus()));
        req.setCancelReason(postOrder.getReasons());
        req.setOutRefundNo(postOrder.getOutRefundNo());
        CancelOrderReq.PostOrderCancel cancel = new CancelOrderReq.PostOrderCancel();
        cancel.setRefundAmount(postOrder.getActRefundAmount());
        cancel.setPostOrderItemList(omsPostOrderItemVos);
        req.setPostOrderCancel(cancel);
        CancelOrderContext.Result result = orderManger.cancelOrderFormPostOrder(req);
        if (result.getSuccess()) {
            OmsOrder update = new OmsOrder();
            update.setActReceiveAmount(order.getActReceiveAmount().subtract(postOrder.getActRefundAmount()));
            update.setRefundAmount(postOrder.getActRefundAmount().add(order.getRefundAmount()));
            update.setRefundStatus(OrderEnums.RefundStatus.PART.getCode());
            update.setPostStatus(PART_3.getCode());
            if (update.getRefundAmount().compareTo(order.getActPayPrice()) >= 0) {
                update.setRefundStatus(OrderEnums.RefundStatus.ALL.getCode());
                update.setPostStatus(null);
            }
            omsOrderService.updateOrderWithInfo(order.getId(), update);
        } else {
            throw new ServiceException(result.getMsg());
        }

    }

    /**
     * 计算是否取消订单
     *
     * @param actRefundAmount
     * @param refundAmount
     * @param actPayPrice
     * @param status
     * @return
     */
    private Integer calCancelCode(BigDecimal actRefundAmount, BigDecimal refundAmount, BigDecimal actPayPrice, Integer status) {
        if (actRefundAmount.add(refundAmount).compareTo(actPayPrice) >= 0) {
            return OrderEnums.OrderStatus.CANCEL_500.getCode();
        } else {
            return OrderEnums.OrderStatus.getByCode(status).getCode();
        }
    }

    @Override
    public void onSuccess() throws Exception {
        PostOrderRefundContext context = this.getContextBean(PostOrderRefundContext.class);
        OmsPostOrderVo postOrder = context.getPostOrder();
        // 发送事件
        OrderOptionLogEvent createEvent = new OrderOptionLogEvent();
        createEvent.setOrderSn(postOrder.getPostOrderNo());
        createEvent.setUserId(postOrder.getUserId());
        createEvent.setUserType(context.getUserType());
        createEvent.setMerId(postOrder.getMerId());
        createEvent.setOrderLogEnums(OrderOptionLogEvent.OrderLogEnums.POST_ORDER);
        createEvent.setContent(OrderOptionLogEvent.PostOrderContentFormatEnums.REFUND_POST_ORDER.formatContent(postOrder.getActRefundAmount().toString()));
        EventHelper.publishEvent(createEvent);
        context.setResult(new PostOrderRefundContext.RefundResult(true));
    }
}
